//
// Copyright (c) 2002-2010 "Neo Technology,"
//     Network Engine for Objects in Lund AB [http://neotechnology.com]
// 
// This file is part of Neo4j.
// 
// Neo4j is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
// 
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// 
namespace org.neo4j.graphdb
{
    /// <summary>  
    /// A client hook for evaluating whether a specific node should be returned from
    ///  a traverser.
    ///  When a traverser is created the client parameterizes it with an instance of a
    ///  ReturnableEvaluator. The traverser then invokes the {@link #IsReturnableNode
    ///  IsReturnableNode()} operation just before returning a specific node, allowing
    ///  the client to either approve or disapprove of returning that node.
    ///  When implementing a ReturnableEvaluator, the client investigates the
    ///  information encapsulated in a <seealso cref="TraversalPosition"/> to decide whether a
    ///  node is returnable. For example, here's a snippet detailing a
    ///  ReturnableEvaluator that will return all leaf nodes: 
    ///  <pre>
    ///  <code>
    ///  ReturnableEvaluator returnEvaluator = new ReturnableEvaluator()
    ///  {
    ///      public boolean <seealso cref="IsReturnableNode(TraversalPosition)"/>( <seealso cref="TraversalPosition "/> position )
    ///      {
    ///          // Return nodes that don't have any outgoing relationships,
    ///          // only incoming relationships, i.e. leaf nodes.
    ///          return !position.<seealso cref="TraversalPosition#currentNode() currentNode"/>().<seealso cref="Node#hasRelationship(Direction) hasRelationship"/>(
    ///              <seealso cref="Direction#OUTGOING Direction.OUTGOING"/> );
    ///      }
    ///  };
    ///  </code>
    ///  </pre> 
    /// </summary>
    public class ReturnableEvaluator
    {
        #region Delegates

        /// <summary>  
        /// Method invoked by traverser to see if the current position is a returnable node.
        /// </summary>
        /// <param name="currentPosition">the traversal position </param>
        /// <returns>
        /// True if current position is a returnable node
        /// </returns>
        public delegate bool IsReturnableNode(TraversalPosition currentPosition);

        #endregion

        #region Implementations

        ///  <summary> 
        ///   A returnable evaluator that returns all nodes encountered.
        ///  </summary>
        IsReturnableNode ALL = delegate
        {
            return true;
        };
        ///  <summary>  
        /// A returnable evaluator that returns all nodes except the start node.
        /// </summary>
        IsReturnableNode ALL_BUT_START_NODE = delegate(TraversalPosition currentPosition)
        {
            return currentPosition.NotStartNode(); 
        };

        #endregion
    }
}